package cn.com.manager.filter;

import java.io.IOException;
import java.io.Serializable;
import java.util.Deque;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.DefaultSessionKey;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authz.AuthorizationFilter;
import org.apache.shiro.web.util.WebUtils;

import cn.com.manager.pojo.User;

/**
 * Created by Administrator on 2016/4/18.
 */
public class LoginCountSessionFilter extends AuthorizationFilter {
    private Cache<String,Deque<Serializable>> cache;
    private SessionManager sessionManager;
    private int max;
    private boolean kickoutAfter = false;
    private String kickoutUrl;

    LoginCountSessionFilter(CacheManager cacheManager){
        this.cache = cacheManager.getCache("loginCountCache");
    }

    public void setMax(int max) {
        this.max = max;
    }

    public void setSessionManager(SessionManager sessionManager) {
        this.sessionManager = sessionManager;
    }

    public void setKickoutAfter(boolean kickoutAfter) {
        this.kickoutAfter = kickoutAfter;
    }

    public void setKickoutUrl(String kickoutUrl) {
        this.kickoutUrl = kickoutUrl;
    }


    @Override
    protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object o) throws Exception {
        return false;
    }

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException {
        Subject subject = getSubject(request, response);
        if (!subject.isAuthenticated() && !subject.isRemembered()){
            //没有登录，直接进入登录流程
            return true;
        }
        Session session = subject.getSession();
        User user = (User)subject.getPrincipal();
        String username =  user.getAccount();
        Deque<Serializable> deque = cache.get(username);
        if (deque == null){
            deque = new LinkedList<Serializable>();
            cache.put(username,deque);
        }
        if (!deque.contains(session.getId())){
            deque.push(session.getId());
        }
        while (deque.size() > max){
            Serializable kickoutSessionId;
            if (kickoutAfter){
                kickoutSessionId = deque.removeFirst();
            }else{
                kickoutSessionId = deque.removeLast();
            }
           try{
               Session kickoutSession = sessionManager.getSession(new DefaultSessionKey(kickoutSessionId));
               if (kickoutSession!=null){
                   kickoutSession.setAttribute("kickout",true);
               }
           }catch (Exception e){

           }
        }
        if (session.getAttribute("kickout")!=null){
            subject.logout();
            saveRequest(request);
            Map<String,Object> param = new HashMap<>();
            param.put("kickout","账号被顶掉！");
            WebUtils.issueRedirect(request,response,kickoutUrl,param);
           /* request.setAttribute("message","账号顶掉！");
            saveRequestAndRedirectToLogin(request,response);*/
            return false;
        }
        return true;
    }
}
